package br.uvv.sao.dao;

import java.util.ArrayList;
import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.FetchMode;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;

import br.uvv.sao.domain.PaginasImplementadas;
import br.uvv.sao.domain.Perfil;
import br.uvv.sao.domain.Permissao;
import br.uvv.sao.util.HibernateUtil;

public class PermissaoDAO extends DAO {
	
	private static final long serialVersionUID = 8420502402226291015L;
	
	@SuppressWarnings("unchecked")
	public List<Perfil> listarPerfis(int first, int pageSize, String sortField,
			boolean sortOrder, String nome) {
		List<Perfil> perfilList = new ArrayList<Perfil>();
		try {
			this.sessao = HibernateUtil.getSessionfactory().getCurrentSession();
			this.transacao = this.sessao.beginTransaction();
			Criteria criteria = this.sessao.createCriteria(Perfil.class);
			criteria.add(Restrictions.ilike("nome", "%" + nome + "%"));
			criteria.setFirstResult(first);
			criteria.setMaxResults(pageSize);
			if(sortField != null){
				if(sortOrder){
					criteria.addOrder(Order.desc(sortField));
				}else{
					criteria.addOrder(Order.asc(sortField));
				}
			}else{
				criteria.addOrder(Order.asc("id"));
			}
			perfilList = criteria.list();
			this.transacao.commit();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return perfilList;
	}

	public int perfilCount(String nome) {
		try {
			this.sessao = HibernateUtil.getSessionfactory().getCurrentSession();
			this.transacao = this.sessao.beginTransaction();
			Criteria criteria = this.sessao.createCriteria(Perfil.class);
			criteria.add(Restrictions.ilike("nome", "%" + nome + "%"));
			criteria.setProjection(Projections.rowCount());
			Long total = (Long) criteria.uniqueResult();
			this.transacao.commit();
			return Integer.parseInt(total.toString());
		} catch (Exception e) {
			e.printStackTrace();
		}
		return 0;
	}

	@SuppressWarnings("unchecked")
	public List<PaginasImplementadas> listarPermissaoSource(
			Perfil perfilInstance, List<PaginasImplementadas> paginas) {
		List<PaginasImplementadas> paginaList = new ArrayList<PaginasImplementadas>();
		try {
			this.sessao = HibernateUtil.getSessionfactory().getCurrentSession();
			this.transacao = this.sessao.beginTransaction();
			Criteria criteria = this.sessao.createCriteria(PaginasImplementadas.class);
			if(paginas.size() > 0){
				List<Long> idsPermitidos = new ArrayList<Long>();
				for (PaginasImplementadas pagina : paginas) {
					idsPermitidos.add(pagina.getId());
				}
				criteria.add(Restrictions.not(Restrictions.in("id", idsPermitidos)));
			}
			paginaList = criteria.list();
			System.out.println("Total source: " + paginaList.size());
			this.transacao.commit();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return paginaList;
	}

	@SuppressWarnings("unchecked")
	public List<PaginasImplementadas> listarPermissaoTarget(
			Perfil perfilInstance) {
		List<PaginasImplementadas> paginaList = new ArrayList<PaginasImplementadas>();
		try {
			this.sessao = HibernateUtil.getSessionfactory().getCurrentSession();
			this.transacao = this.sessao.beginTransaction();
			Criteria criteria = this.sessao.createCriteria(PaginasImplementadas.class);
			criteria.createCriteria("permissoes").add(Restrictions.eq("perfil", perfilInstance));
			paginaList = criteria.list();
			System.out.println("Total target: " + paginaList.size());
			this.transacao.commit();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return paginaList;
	}

	@SuppressWarnings({ "unchecked", "deprecation" })
	public List<Permissao> listarPermissoes(int first, int pageSize, String sortField,
			boolean sortOrder, Perfil perfilInstance) {
		List<Permissao> permissaoList = new ArrayList<Permissao>();
		try {
			this.sessao = HibernateUtil.getSessionfactory().getCurrentSession();
			this.transacao = this.sessao.beginTransaction();
			Criteria criteria = this.sessao.createCriteria(Permissao.class);
			criteria.add(Restrictions.eq("perfil", perfilInstance));
			criteria.setFetchMode("pagina", FetchMode.EAGER);
			criteria.setFirstResult(first);
			criteria.setMaxResults(pageSize);
			if(sortField != null){
				if(sortOrder){
					criteria.addOrder(Order.desc(sortField));
				}else{
					criteria.addOrder(Order.asc(sortField));
				}
			}else{
				criteria.addOrder(Order.asc("id"));
			}
			permissaoList = criteria.list();
			this.transacao.commit();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return permissaoList;
	}
	
	public Integer permissoesCount(Perfil perfilInstance) {
		Long count = 0L;
		try {
			this.sessao = HibernateUtil.getSessionfactory().getCurrentSession();
			this.transacao = this.sessao.beginTransaction();
			Criteria criteria = this.sessao.createCriteria(Permissao.class);
			criteria.add(Restrictions.eq("perfil", perfilInstance));
			criteria.setProjection(Projections.rowCount());
			count = (Long) criteria.uniqueResult();
			this.transacao.commit();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return Integer.parseInt(count.toString());
	}

	@SuppressWarnings("unchecked")
	public PaginasImplementadas getPagina(String url) {
		System.out.println("veio pegar a pagina");
		PaginasImplementadas paginaInstance = new PaginasImplementadas();
		try {
			this.sessao = HibernateUtil.getSessionfactory().getCurrentSession();
			this.transacao = this.sessao.beginTransaction();
			Criteria criteria = this.sessao.createCriteria(PaginasImplementadas.class);
			criteria.add(Restrictions.eq("url", url));
			List<PaginasImplementadas> modelInstance = (ArrayList<PaginasImplementadas>) criteria.list();
			this.transacao.commit();
			if(modelInstance != null && modelInstance.size() > 0){
				paginaInstance = modelInstance.get(0);
			}
			System.out.println("pegou: " + paginaInstance.getId());
		} catch (Exception e) {
			e.printStackTrace();
		}
		return paginaInstance;
	}
	
	@SuppressWarnings("unchecked")
	public Permissao getPermissao(Perfil perfil, PaginasImplementadas pagina) {
		System.out.println("veio pegar a permissao");
		Permissao permissaoInstance = new Permissao();
		try {
			this.sessao = HibernateUtil.getSessionfactory().getCurrentSession();
			this.transacao = this.sessao.beginTransaction();
			Criteria criteria = this.sessao.createCriteria(Permissao.class);
			criteria.add(Restrictions.eq("perfil", perfil));
			criteria.add(Restrictions.eq("pagina", pagina));
			List<Permissao> modelInstance = (ArrayList<Permissao>) criteria.list();
			this.transacao.commit();
			if(modelInstance != null && modelInstance.size() > 0){
				permissaoInstance = modelInstance.get(0);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return permissaoInstance;
	}

	public void removerPermissao(Permissao permissao) {
		try {
			this.sessao = HibernateUtil.getSessionfactory().getCurrentSession();
			this.transacao = this.sessao.beginTransaction();
			this.sessao.delete(permissao);
			this.transacao.commit();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public void salvarPermissao(Perfil perfil, PaginasImplementadas pagina) {
		Permissao permissao = new Permissao();
		permissao.setPerfil(getPerfil(perfil.getId()));
		permissao.setPagina(getPagina(pagina.getUrl()));
		try {
			this.sessao = HibernateUtil.getSessionfactory().getCurrentSession();
			this.transacao = this.sessao.beginTransaction();
			this.sessao.save(permissao);
			this.transacao.commit();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public void atualizarPermissao(Permissao permissao) {
		try {
			this.sessao = HibernateUtil.getSessionfactory().getCurrentSession();
			this.transacao = this.sessao.beginTransaction();
			this.sessao.update(permissao);
			this.transacao.commit();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public Perfil getPerfil(Long id) {
		System.out.println("veio pegar a pagina");
		try {
			this.sessao = HibernateUtil.getSessionfactory().getCurrentSession();
			this.transacao = this.sessao.beginTransaction();
			Perfil model = (Perfil) this.sessao.load(Perfil.class, id);
			this.transacao.commit();
			return model;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return new Perfil();
	}

}
